<?php

if (! defined ( 'BASEPATH' ))
	exit ( 'No direct script access allowed' );

class Controller_User extends CI_Controller {
	public function __construct() {
		parent::__construct ();
		require(APPPATH.'helpers/protocal.php');
		$this->load->model ( 'Model_User', 'User' );
	}
	
private function configure_email() {
		$this->load->library ( 'email' );
		
		$config ['wordwrap'] = TRUE;
		$config ['protocol'] = 'smtp';
		$config ['smtp_host'] = SMTP_HOST;
		$config ['smtp_user'] = COMPANY_EMAIL;
		$config ['smtp_pass'] = EMAIL_PASS;
		$config ['smtp_port'] = SMTP_PORT;
		$config ['smtp_timeout'] = '5';
		$config ['newline'] = "\r\n";
		$config ['charset'] = 'utf-8';
		$config ['crlf'] = "\r\n";
		$this->email->initialize ( $config );
		
		$this->email->from ( COMPANY_EMAIL, COMPANY_NAME );
	}
	private function send_register_email($email, $username, $password) {
		$this->configure_email ();
		$this->email->to ( $email );
		$this->email->subject ( "安琪娃娃注册信息" );
		$message = "您在安琪娃娃游戏中的注册邮箱是 " . $email . ", 注册的用户名是 " . $username . ", 登陆密码是 " . $password . "。 如果您在另外的设备上登陆时，请使用以上注册信息登陆。 祝您游戏愉快!";
		$this->email->message ( $message );
		if (! $this->email->send ()) {
			log_message ( 'error', 'send email failed ' . $this->email->print_debugger () );
			return FALSE;
		} else {
			log_message ( 'debug', 'send email success ' . $this->email->print_debugger () );
			return TRUE;
		}
	}
	private function send_modify_email($email, $username, $password) {
		$this->configure_email ();
		$this->email->to ( $email );
		$this->email->subject ( '安琪娃娃注册信息修改' );
		$this->email->message ( "您在安琪娃娃中的注册邮箱是 '$email', 注册的用户名修改为 '$username'。如果您在另外的设备上登陆时，请使用以上注册信息登陆。 祝您游戏愉快!" );
		if (! $this->email->send ()) {
			log_message ( 'error', 'send email failed ' . $this->email->print_debugger () );
			return FALSE;
		} else {
			return TRUE;
		}
	}
	// return_code: 0 success, 1 email not exist, 2 database failed, 3 send
	// email failed, -1 unkown error
	protected function reset_password() {
		
		$result = null;
		$result->return_code = - 1;
		$result->protocal = get_protocal( $_GET ['protocal'] );
		$email = $_GET ['email'];
		
		$user = $this->User->get_user_by_email ( $email );
		if ($user != null) {
			$origin_password = $this->generate_password ();
			$password = $this->md5_password ( $origin_password );
			
			$query1 = $this->User->modify_password ( $user->userid, $password );
			if (! $query1) {
				$result->return_code = 2;
				goto label_return;
			}
			
			$this->configure_email ();
			$this->email->to ( $email );
			$this->email->subject ( '安琪娃娃忘记密码' );
			$this->email->message ( "您在安琪娃娃中的注册邮箱是 '$email', 用户名为 '$user->username', 密码初始化为 '$origin_password'。请使用以上信息重新登陆。 祝您游戏愉快!" );
			if (! $this->email->send ()) {
				log_message ( 'error', 'send email failed ' . $this->email->print_debugger () );
				$result->return_code = 3;
				goto label_return;
			} else {
				$result->return_code = 0;
				goto label_return;
			}
		} else {
			$result->return_code = 1;
			goto label_return;
		}
		
		label_error:
		$result->return_code = - 1;
		goto  label_return;
		
		label_return:
		$this->output->set_output ( json_encode ( $result ) );
	}
	private function generate_password($length = 8) {
		$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
		$password = '';
		for($i = 0; $i < $length; $i ++) {
			$password .= $chars [mt_rand ( 0, strlen ( $chars ) - 1 )];
		}
		return $password;
	}
	private function md5_password($password) {
		$this->load->helper ( 'security' );
		$result = do_hash ( $password . SERVER_MD5_KEY, 'md5' ); // MD5
		return strtoupper ( $result );
	}
	// 0:success 1:register success 2 email have exist 3: username have exist 5:
	// email and username both have exist
	// -1:unkown error 4: relogin success 6:register failed 7:password not match
	// 8 username not match 9:need password
	private function login_by_email($userid, $email, $username, $password) {
		$result = null;
		$result->return_code = - 1;
		$result->protocal = get_protocal( $_GET ['protocal'] );
		$result->method = get_login_type( $_GET ['protocal'] );
		$user = null;
		log_message ( 'debug', "method = $result->method" );
		
		if ($userid && $email && $username && $password) {
			$user = $this->User->get_user_by_userid ( $userid );
			if ($user != null) {
				if (strtoupper ( $email ) == strtoupper ( $user->email ) && $password == $user->password) {
					log_message ( 'debug', "return_code = 0  userid = $user->userid  email = $user->email" );
					if ($username == $user->username) {
						$result->return_code = 0;
					} else {
						$result->return_code = 8;
					}
					$result->user = $user;
					goto label_success;
				}
			}
		}
		if ($email != null) {
			$user = $this->User->get_user_by_email ( $email );
			if ($user != null) {
				if ($password == null) {
					//log_message ( 'debug', "return_code = 9  userid = $user->userid  email = $user->email" );
					
					$result->return_code = 9;
					goto label_return;
				} else if ($password == $user->password) {
					$result->return_code = 4;
					$result->user = $user;
					goto label_success;
				} else {
					log_message ( 'debug', "client password '$password' and database password '$user->password'" );
					$result->return_code = 7;
					goto label_return;
				}
			} else { // register
				if ($username != null) {
					$user = $this->User->get_user_by_name ( $username );
					if ($user != null) {
						$result->return_code = 3;
					}
				}
				if ($result->return_code != - 1) {
					goto label_return;
				} else {
					log_message ( 'debug', "register" );
					goto label_register;
				}
			}
		}
		goto label_return;
		
		label_register:
		$origin_password = $this->generate_password ();
		$password = $this->md5_password ( $origin_password );
		if ($username == null) {
			$add_user = $this->User->add_user_with_email ( $email, $password, null );
		} else {
			$add_user = $this->User->add_user_with_email ( $email, $password, $username );
		}
		if ($add_user->return_code == 0) { // add user success
			$result->return_code = 1;
			$user->userid = $add_user->userid;
			$user->email = $email;
			$user->password = $password;
			if ($username == null) {
				$username = "fashion" . $user->userid;

				require(BASEPATH.'helpers/date_helper.php');
				$ftime = strftime ( "%Y-%m-%d %H:%M:%S", now() );
				$this->User->modify_username ( $user->userid, $username, $ftime );
			}
			$user->username = $username;
			$result->user = $user;
			$this->send_register_email ( $email, $username, $origin_password );
			goto label_success;
		} else {
			$result->return_code = 6;
			goto label_return;
		}
		label_success:
		if ($result->return_code != 1) {
			$use_wifi = false;
			$device_token = null;
			if (isset ( $_POST ['wifi'] )) {
				$use_wifi = true;
			}
			if (isset ( $_POST ['device_token'] )) {
				$device_token = $_POST ['device_token'];
			}
			//$this->User->update_device ( $user->userid, $use_wifi, $device_token );
		}
		goto label_return;
		
		label_return:
		log_message('debug', "login $result->return_code");
		$this->output->set_output ( json_encode ( $result ) );
	}
	private function login_by_91($userid, $uin91, $username) {
		$result = null;
		$result->return_code = -1;
		$result->protocal = get_protocal( $_GET['protocal'] );
		$result->method = get_login_type( $_GET['protocal'] );
		$user = null;

		if ($userid != null) {
			$user = $this->User->get_user_by_userid( $userid );
			if ($user != null) {
				if ($uin91 == $user->uin91) {
					$result->return_code = 0;
					$result->user = $user;
					goto label_success;
				}
			}
		}
		$user = $this->User->get_user_by_uin91( $uin91 );
		if ($user != null) {
			$result->return_code = 4;
			$result->user = $user;
			goto label_success;
		}
		$add_user = $this->User->add_user_with_91( $result->method, $uin91, $username );
		if ($add_user->return_code == 0) {
			$result->return_code = 1;
			$user->userid = $add_user->userid;
			$user->uin91 = $uin91;
			if ($username == null) {
				require(BASEPATH.'helpers/date_helper.php');
				$ftime = strftime ( "%Y-%m-%d %H:%M:%S", now() );
				$user->username = "fashion".$add_user->userid;
				$this->User->modify_username( $user->userid, $user->username, $ftime);
			}
			else {
				$user->username = $username;
			}
			$result->user = $user;
			goto label_success;
		}
		else {
			$result->return_code = 6;
			goto label_return;
		}
label_success:
		if ($result->return_code != 1) {
			$query = $this->User->get_user_by_name_except($user->userid, $username);
			if ($query != null) {
				$user->username = "fashion" . $user->userid;
				require(BASEPATH.'helpers/date_helper.php');
				$ftime = strftime ( "%Y-%m-%d %H:%M:%S", now() );
				$this->User->modify_username ( $user->userid, $user->username, $ftime );
			}
			
			$use_wifi = false;
			$device_token = null;
			if (isset( $_POST['wifi'])) {
				$use_wifi = true;
			}
			if (isset( $_POST['device_token'])) {
				$device_token = $_POST['device_token'];
			}
			//$this->User->update_device( $user->userid, $use_wifi, $device_token );
		}
		goto label_return;
label_return:
		$this->output->set_output( json_encode( $result ) );
	}
	private function login_by_other($userid, $access_token) {
		$result = null;
		$result->return_code = - 1;
		$result->protocal = get_protocal( $_GET ['protocal'] );
		$result->method = get_login_type( $_GET ['protocal'] );
		$user = null;
		
		if ($userid != null) {
			$user = $this->User->get_user_by_userid ( $userid );
			if ($user != null) {
				if ($access_token == $user->access_token) {
					$result->return_code = 0;
					$result->user = $user;
					goto label_success;
				}
			}
		}
		$user = $this->User->get_user_by_access_token ( $access_token );
		if ($user != null) {
			$result->return_code = 4;
			$result->user = $user;
			goto label_success;
		}
		// register
		$add_user = $this->User->add_user_with_access_token ( $result->method, $access_token );
		if ($add_user->return_code == 0) { // add user success
			
			$result->return_code = 1;
			$user->userid = $add_user->userid;
			$user->username = "fashion" . $add_user->userid;

			require(BASEPATH.'helpers/date_helper.php');
			$ftime = strftime ( "%Y-%m-%d %H:%M:%S", now() );
			$this->User->modify_username ( $user->userid, $user->username, $ftime );
			
			$result->user = $user;
			goto label_success;
		} else {
			$result->return_code = 6;
			goto label_return;
		}
		label_success:
		if ($result->return_code != 1) {
			$use_wifi = false;
			$device_token = null;
			if (isset ( $_POST ['wifi'] )) {
				$use_wifi = true;
			}
			if (isset ( $_POST ['device_token'] )) {
				$device_token = $_POST ['device_token'];
			}
			//$this->User->update_device ( $user->userid, $use_wifi, $device_token );
		}
		goto label_return;
		
		label_return:
		$this->output->set_output ( json_encode ( $result ) );
	}
	protected function login() {
		$userid = null;
		$email = null;
		$access_token = null;
		$username = null;
		$password = null;
		
		$result = null;
		$result->protocal = get_protocal( $_GET ['protocal'] );
		$method = get_login_type( $_GET ['protocal'] );
		if (isset ( $_GET ['userid'] )) {
			$userid = $_GET ['userid'];
		}
		if (isset ( $_POST ['email'] )) {
			$email = $_POST ['email'];
		}
		if (isset ( $_POST ['username'] )) {
			$username = $_POST ['username'];
		}
		if (isset ( $_POST ['password'] )) {
			$password = strtoupper ( $_POST ['password'] );
		}
		if (isset ( $_POST ['access_token'] )) {
			$access_token = $_POST ['access_token'];
		}
		if (($method & EMAIL_LOGIN) == EMAIL_LOGIN) {
			$this->login_by_email ( $userid, $email, $username, $password );
		} else if (($method & TENCENT_LOGIN)== TENCENT_LOGIN || ($method & SINA_LOGIN) == SINA_LOGIN) {
			$this->login_by_other ( $userid, $access_token );
		}
		else if (($method & LOGIN_91) == LOGIN_91) {
			log_message('debug', 'login_by_91');
			$this->login_by_91( $userid, $access_token, $username);
		}
		
		if ($userid != null) {
			require(BASEPATH.'helpers/date_helper.php');
			$ftime = strftime ( "%Y-%m-%d %H:%M:%S", now() );
			$this->User->update_latest_login_time ( $userid, $ftime );
		}
	}
	
	// 修改个人资料
	// return_code : 2 other error; 1 username have exist
	protected function modify() {
		$result = null;
		$result->return_code = 0;
		$result->protocal = get_protocal( $_GET ['protocal'] );
		$userid = $_GET ['userid'];
		$new_password = null;
		$email = null;
		if (isset ( $_POST ['new_password'] )) {
			$new_password = $_POST ['new_password'];
		}
		$new_username = null;
		if (isset ( $_POST ['new_username'] )) {
			$new_username = $_POST ['new_username'];
		}
		if (isset ( $_POST ['email'] )) {
			$email = $_POST ['email'];
		}
		if ($new_username != null) {
			$query1 = $this->User->get_user_by_name ( $new_username );
			if ($query1 != null) {
				goto label_username_have_exist;
			}
		}

		require(BASEPATH.'helpers/date_helper.php');
		$ftime = strftime ( "%Y-%m-%d %H:%M:%S", now() );
		$user = $this->User->get_user_by_userid( $userid );
		if ($user != null) {
			if ($new_username != null && $user->username != $new_username) {
				$query1 = $this->User->modify_username ( $userid, $new_username, $ftime );
				if (! $query1) { // 发生错误，roll back
					goto label_other_error;
				}
			}
			if ($new_password != null && $user->password != $new_password) {
				$query1 = $this->User->modify_password ( $userid, $new_password );
				if (! $query1) {
					goto label_other_error;
				}
			}
			if ($email != null) {
				$this->send_modify_email ( $email, $new_username, $new_password );
			}
		}
		if ($new_username != null) {
			$result->username = $new_username;
		}
		if ($new_password != null) {
			$result->password = $new_password;
		}
		goto label_return;
		
		label_other_error:
		$result->return_code = 2;
		goto label_return;
		label_username_have_exist:
		$result->return_code = 1;
		goto label_return;
		label_return:
		$this->output->set_output ( json_encode ( $result ) );
	}
	
	// return_code : 1 add failed
	protected function send_device_info() {
		$result = null;
		$result->return_code = 0;
		$result->protocal = get_protocal( $_GET ['protocal'] );
		$userid = $_GET ['userid'];
		$version = $_GET ['version'];
		$model = null;
		if (isset( $_POST['model'] )) {
			$model = $_POST ['model'];
		}
		$udid = null;
		if (isset( $_POST['udid'] )) {
			$udid = $_POST ['udid'];
		}
		$device_token = null;
		if (isset ( $_POST ['device_token'] )) {
			$device_token = $_POST ['device_token'];
		}
		$bUseWifi = false;
		if (isset ( $_GET ['wifi'] )) {
			$bUseWifi = true;
		}
		log_message ( 'debug', 'send_device_info' );
		$ret = $this->User->add_device ( $userid, $udid, $model, $version, $device_token, $bUseWifi );
		if (! $ret) {
			$result->return_code = 1;
		}
		$this->output->set_output ( json_encode ( $result ) );
	}
	
	public function index() {
		$protocal = get_protocal( $_GET['protocal'] );
		switch ($protocal) {
			case 1001 :
				$this->login();
				break;
			case 1002 :
				$this->modify();
				break;
			case 1003 :
				$this->send_device_info();
				break;
			case 1004 :
				$this->reset_password();
				break;
			default :
				break;
		}
	}
}
